package com.ideal.gpt.ability.doccompare;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;

import com.alibaba.fastjson.JSONObject;
import com.ideal.gpt.GptJobConfig;
import com.ideal.gpt.ability.doccompare.DocCompare.DiffInfo;
import com.lzwork.doclib.DocElement;
import com.lzwork.doclib.WordLoader;
import com.lzwork.utility.data.NumberParse;
import com.lzwork.utility.file.FileUtility;
import com.lzwork.utility.file.FileUtility.FileType;
import com.lzwork.utility.file.LineContent;
import com.lzwork.utility.file.LineContent.LoadSetting;
import com.lzwork.utility.logger.LOGGER;
import com.lzwork.utility.str.StrUtility;
import com.lzwork.web.BaseController;
import com.lzwork.web.JsonKey;
import com.lzwork.web.data.CallResultInfo;

/**
 * @author LiZheng
 * @date 2023年10月19日 下午2:06:26
 */

@Controller
@RequestMapping(value = "/diff/*")
public class DiffController extends BaseController
{
	File tf = null;

	File tempFoler()
	{
		if (tf == null)
			tf = FileUtility.getFileSafe(GptJobConfig.root(), "diffTemp/");
		return tf;
	}

	@PostMapping(value = "/compareAll", produces = "application/json;charset=UTF-8")
	@ResponseBody
	public JSONObject compareAll(@RequestBody Map<?, ?> map)
	{
		JSONObject result = new JSONObject();

		result.put("diff", compareDiff(map));
		result.put("vec", vecSim(map));
		result.put("dist", distSim(map));
		result.put("ai", aiAbstract(map));

		return result;
	}

	@PostMapping(value = "/compareDiff", produces = "application/json;charset=UTF-8")
	@ResponseBody
	public JSONObject compareDiff(@RequestBody Map<?, ?> map)
	{
		JSONObject result = new JSONObject();
		String dataL = getMapStr(map, "first");
		String dataR = getMapStr(map, "second");

		DiffInfo tp = DocCompare.getCompareResult(dataL, dataR, false);
		result.put("diffL", tp.sourceDiff());
		result.put("diffR", tp.targetDiff());
		result.put("sizeL", dataL.length());
		result.put("sizeR", dataR.length());
		return result;
	}

	@PostMapping(value = "/vecSim", produces = "application/json;charset=UTF-8")
	@ResponseBody
	public JSONObject vecSim(@RequestBody Map<?, ?> map)
	{
		float sim = DocCompare.getVectorSimulate(getMapStr(map, "first"), getMapStr(map, "second"));
		String simStr = NumberParse.toPercent(sim);

		JSONObject result = new JSONObject();
		result.put("simNum", sim);
		result.put("simStr", simStr);

		return result;
	}

	@PostMapping(value = "/distSim", produces = "application/json;charset=UTF-8")
	@ResponseBody
	public JSONObject distSim(@RequestBody Map<?, ?> map)
	{
		float sim = DocCompare.getDistantSimulate(getMapStr(map, "first"), getMapStr(map, "second"));
		String simStr = NumberParse.toPercent(sim);

		JSONObject result = new JSONObject();
		result.put("simNum", sim);
		result.put("simStr", simStr);

		return result;
	}

	@PostMapping(value = "/aiAbstract", produces = "application/json;charset=UTF-8")
	@ResponseBody
	public JSONObject aiAbstract(@RequestBody Map<?, ?> map)
	{
		CallResultInfo<String> bInfo = DocCompare.chatCompare(getMapStr(map, "first"), getMapStr(map, "second"), false);

		JSONObject result = new JSONObject();
		if (bInfo.target() != null)
			result.put("cost", bInfo.target());
		else
			result.put("cost", "");
		result.put("summary", bInfo.info());
		return result;
	}

	@PostMapping(value = "/compare", produces = "application/json;charset=UTF-8")
	@ResponseBody
	public JSONObject fileCompare(MultipartFile fileL, MultipartFile fileR) throws IOException
	{
		JSONObject result = new JSONObject(true);

		File localL = FileUtility.ajaxFileSave(fileL, FileUtility.getFileSafe(tempFoler(), fileL.getOriginalFilename()));
		File localR = FileUtility.ajaxFileSave(fileR, FileUtility.getFileSafe(tempFoler(), fileR.getOriginalFilename()));

		String err = "";

		if (localL.exists() && localR.exists())
		{
			String dataL = StrUtility.combineString(loadFile(localL), "\n");
			String dataR = StrUtility.combineString(loadFile(localR), "\n");

			if (dataL.isEmpty())
				err = "First file is empty!";
			else if (dataL.isEmpty())
				err = "Second file is empty!";
			else
			{
				DiffInfo tp = DocCompare.getCompareResult(dataL, dataR, false);
				result.put("diffL", tp.sourceDiff());
				result.put("diffR", tp.targetDiff());
				result.put("sizeL", dataL.length());
				result.put("sizeR", dataR.length());

				CallResultInfo<String> bInfo = DocCompare.chatCompare(dataL, dataR, null, DocCompare::policyComparePrompt, false);

				if (bInfo.target() != null)
					result.put("cost", bInfo.target());
				else
					result.put("cost", "");
				result.put("summary", bInfo.info());
			}

		} else
			err = "Save file fail.";

		result.put(JsonKey.KEY_ERRMSG, err);

		return result;
	}

	protected List<String> loadFile(File f)
	{
		FileType type = FileUtility.getFileType(f.getName());

		if (type == FileType.TXT)
		{
			List<String> lines = LineContent.loadFile(f, new LoadSetting());
			return lines;
		} else if (type == FileType.DOC)
		{
			DocElement doc = WordLoader.readDoc(f);
			return doc.getAllLines(true);
		}

		LOGGER.log(LOGGER.FILE, "Unknow file type: " + f.getAbsolutePath());
		return new ArrayList<>();
	}
}
